﻿using DotNetCore.CAP;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Configuration;
using System.Reflection;
using System.Reflection.Metadata;
using UnitOfWorkCore.Application;
using UnitOfWorkCore.Domain.Entities;
using UnitOfWorkCore.Infrastructure.Context;

namespace UnitOfWorkCore
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            IServiceCollection services = new ServiceCollection();

            // 构造 ConfigurationBuilder
            var builder = new ConfigurationBuilder();

            // 设置 Configuration 文件夹的路径
            var configurationPath = Path.Combine(System.AppContext.BaseDirectory, "Configuration");

            // 检查 Configuration 文件夹是否存在
            if (Directory.Exists(configurationPath))
            {
                // 获取 Configuration 文件夹下所有的 .json 文件
                var jsonFiles = Directory.EnumerateFiles(configurationPath, "*.json");

                // 将每个 .json 文件追加到 ConfigurationBuilder
                foreach (var jsonFile in jsonFiles)
                {
                    builder.AddJsonFile(jsonFile, optional: false, reloadOnChange: true);
                }
            }

            // 构建 IConfiguration
            IConfiguration config = builder.Build();

            // 将 IConfiguration 注册到服务容器
            services.AddSingleton(config);

            Assembly assembly = Assembly.Load("UnitOfWorkCore");
            var startupType = assembly.GetTypes()
                    .FirstOrDefault(t => typeof(IStartup).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
            var method = startupType.GetMethod("ConfigureServices")
                ?? throw new InvalidOperationException($"Method 'ConfigureServices' not found in type '{startupType.Name}'.");
            method.Invoke(Activator.CreateInstance(startupType), new[] { services });

            services.AddCap(options =>
            {
                // 存储配置
                //options.UseEntityFramework<AppDbContext>();

                // RabbitMQ 配置
                options.UseRabbitMQ(rabbitOptions =>
                {
                    config.GetSection("RabbitMQ").Bind(rabbitOptions);
                });

                //options.DefaultGroupName = "cap-queue"; // 这会作为队列名称的一部分

                options.UseDashboard(); // 启用仪表盘
                options.FailedRetryCount = 5;
                // 当重试次数达到FailedRetryCount（默认为50次）时，重试会停止
                options.FailedRetryInterval = 10; // 设置每次重试间隔为30秒
                                                  //在消息发送或消费过程中，如果发生失败，CAP会立即重试3次，然后在FallbackWindowLookbackSeconds指定的时间后开始轮询重试
                options.FallbackWindowLookbackSeconds = 30; // 设置重试窗口时间为120秒
                options.SucceedMessageExpiredAfter = 180 * 24 * 3600; // 成功消息保留 24 小时
                options.FailedMessageExpiredAfter = 360 * 24 * 3600; // 失败消息保留 7 天
            });

            services.AddScoped<DemoApi>();

            // 构建服务提供器
            IServiceProvider serviceProvider = services.BuildServiceProvider();

            // 初始化数据库
            using (var scope = serviceProvider.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
                dbContext.Database.EnsureCreated(); // 确保 CAP 表已创建
            }

            // 启动 CAP 后台消费者
            var capBootstrapper = serviceProvider.GetRequiredService<IBootstrapper>();
            await capBootstrapper.BootstrapAsync(); // 关键步骤：启动 CAP


            // 执行业务逻辑
            using (var scope = serviceProvider.CreateScope())
            {
                var demo = scope.ServiceProvider.GetRequiredService<DemoApi>();
                await demo.AddUser();

                List<User> user = await demo.QueryUser();
            }

            Console.WriteLine("按任意键退出...");
            Console.ReadKey();

            // 停止 CAP
            await capBootstrapper.DisposeAsync();

            Console.ReadKey();
        }
    }
}
